package com.cjym.GateWay.filters;

import com.cjym.GateWay.entity.AccessLog;
import com.cjym.GateWay.service.AccessLogService;
import com.cjym.GateWay.util.IpUtils;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;

/**
 * @author cjym
 * @date:  2023-12-19
 * @version 1.0
 * 访问日志添加过滤器
 */
@Component
@ConditionalOnProperty(name = "gateway.accessLog.enable", havingValue = "true")
@Slf4j
public class AccessLogFilter implements GlobalFilter, Ordered {

    @Resource
    private AccessLogService accessLogService;

    @Value("${gateway.token.name:#{'token'}}")
    private String tokenName;

    @Value("${gateway.accessLog.descName:#{'desc'}}")
    private String descName;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        //获取相对路径
        String value = request.getPath().value();
        //获取Ip
        String hostIp = IpUtils.getHostIp();
        //获取token
        String token = request.getHeaders().getFirst(tokenName);
        AccessLog accessLog = new AccessLog();
        accessLog.setIp(hostIp);
        accessLog.setRouter(value);
        if(!ObjectUtils.isEmpty(token)) accessLog.setRouter(token);
        String desc = request.getHeaders().getFirst(descName);
        if(!ObjectUtils.isEmpty(desc)) accessLog.setDesc(desc);
        accessLog.setCreateTime(LocalDateTime.now());
        Thread.ofVirtual().start(()->{
            accessLogService.save(accessLog);
        });
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 9;
    }

    @PostConstruct
    public void init() {
        log.info("访问日志过滤器初始化完成");
    }
}
